#!BPY

"""
Name: 'Creavi Keyframe 3D'
Blender: 244
Group: 'Export'
Tooltip: 'Exportador para Creavi Keyframe 3D'
"""

##Copiar este archivo al directorio de Blender, en el subdirectorio .blender/scripts
##Y reiniciar Blender.
##Para usarlo, entrar a File -> Export -> Creavi Keyframe 3D

##El formato Creavi Keyframe 3D es de la siguiente manera:
##model %total %join_points %keyframes //numero de meshes que componen el formato, y la cantidad de "join-points" y de keyframes
##mesh-def %caras //numero de caras (solo triangulos)
##keyframe %tiempo //define el tiempo de un keyframe
##vertex %x %y %z %nX %nY %nZ %u %v //define la posicion de un vertice, su normal y sus coordenadas UV
##join-def %nombre //nombre de los join-points
##keyframe %tiempo %x %y %z %normalX %normalY %normalZ //define el tiempo de un keyframe y coordenadas para un join-def

import Blender
from Blender import Mathutils
from Blender.Mathutils import *

def displayVertex(out, vertex, child, uv):
    punto = (vertex.co * child.getMatrix().rotationPart()) + child.getMatrix().translationPart()
    x = child.getDeltaLocation()[0] + punto[0]
    y = child.getDeltaLocation()[1] + punto[1]
    z = child.getDeltaLocation()[2] + punto[2]
    nX = vertex.no[0]
    nY = vertex.no[1]
    nZ = vertex.no[2]
    if uv == 0:
        u = 0
        v = 0
    else:
        u = uv[0]
        v = uv[1]
    
    out.write("vertex %f %f %f %f %f %f %f %f\n" % (x, y, z, nX, nY, nZ, u, v))
    

def write(filename):
    out = file(filename, "w")
    
    scene = Blender.Scene.GetCurrent()
    startFrame = scene.getRenderingContext().startFrame()
    endFrame = scene.getRenderingContext().endFrame()
    frameMultiplier = 1.0 / scene.getRenderingContext().fps
    
    meshCount = 0
    joinCount = 0
    for child in scene.objects:
        if child.getType() == "Mesh":
            meshCount += 1
        if child.getType() == "Empty":
            joinCount += 1

    out.write("model %i %i %i %f\n" % (meshCount, joinCount, (endFrame - startFrame + 1), frameMultiplier))

    for child in scene.objects:
        if child.getType() == "Mesh":
            nmesh = child.getData()
            fcount = 0
            for face in nmesh.faces:
                if len(face.v) == 3 or len(face.v) == 4:
                    fcount = fcount + 1
                    if len(face.v) == 4:
                        fcount = fcount + 1

            out.write("mesh-def %i\n" % (fcount))
            
            for frame in range(startFrame, endFrame + 1):
                out.write("keyframe %f\n" % ((frame - startFrame) * frameMultiplier))
                Blender.Set("curframe", frame)
                
                faceIdx = 0
                for face in nmesh.faces:
                    if len(face.v) == 3 or len(face.v) == 4:
                        vert1 = face.v[0].index
                        vert2 = face.v[1].index
                        vert3 = face.v[2].index
                        if len(face.uv) > 0:
                            displayVertex(out, nmesh.verts[vert1], child, face.uv[0])
                            displayVertex(out, nmesh.verts[vert2], child, face.uv[1])
                            displayVertex(out, nmesh.verts[vert3], child, face.uv[2])
                        else:
                            displayVertex(out, nmesh.verts[vert1], child, 0)
                            displayVertex(out, nmesh.verts[vert2], child, 0)
                            displayVertex(out, nmesh.verts[vert3], child, 0)
                        
                        if len(face.v) == 4:
                            vert1 = face.v[0].index
                            vert2 = face.v[2].index
                            vert3 = face.v[3].index
                            if len(face.uv) > 0:
                                displayVertex(out, nmesh.verts[vert1], child, face.uv[0])
                                displayVertex(out, nmesh.verts[vert2], child, face.uv[2])
                                displayVertex(out, nmesh.verts[vert3], child, face.uv[3])
                            else:
                                displayVertex(out, nmesh.verts[vert1], child, 0)
                                displayVertex(out, nmesh.verts[vert2], child, 0)
                                displayVertex(out, nmesh.verts[vert3], child, 0)
                            

    for child in scene.objects:
        if child.getType() == "Empty":
            nmesh = child.getData()
            out.write("join-def %s\n" % (child.name))
            
            for frame in range(startFrame, endFrame + 1):
                Blender.Set("curframe", frame)
                
                frameSet = ((frame - startFrame) * frameMultiplier)
                punto = child.loc
                x = child.getDeltaLocation()[0] + punto[0]
                y = child.getDeltaLocation()[1] + punto[1]
                z = child.getDeltaLocation()[2] + punto[2]
                nX = child.rot[0]
                nY = child.rot[1]
                nZ = child.rot[2]
                
                out.write("keyframe %f %f %f %f %f %f %f\n" % (frameSet, x, y, z, nX, nY, nZ))

inicial = Blender.Get("curframe")
Blender.Window.FileSelector(write, "Export")
Blender.Set("curframe", inicial)
